/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ucmconfchecker.UI;

import edu.uci.ics.jung.algorithms.layout.FRLayout;
import edu.uci.ics.jung.algorithms.layout.Layout;
import edu.uci.ics.jung.graph.Graph;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.geom.Point2D;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.collections15.Transformer;
import ucmconfchecker.conformance.Edge;
import ucmconfchecker.conformance.Scenario;
import ucmconfchecker.pArchitecture.Component;
import ucmconfchecker.pArchitecture.Responsibility;

/**
 *
 * @author Alex
 */
public class PrecedenceLayout<T> implements Layout<T,Edge> {
    private Scenario<T> g;
    Layout<T,Edge> layout;
    
    public PrecedenceLayout(Scenario<T> g){
        this.g=g;
        layout = new FRLayout<T,Edge>(g);
    }
    public void initialize() {
        //throw new UnsupportedOperationException("Not supported yet.");
    }

    public void setInitializer(Transformer<T, Point2D> t) {
        //throw new UnsupportedOperationException("Not supported yet.");
    }

    public void setGraph(Graph<T, Edge> graph) {
        this.g = (Scenario<T>)graph;
        update();
    }

    public Graph<T, Edge> getGraph() {
        return g;
    }

    public void reset() {
        //throw new UnsupportedOperationException("Not supported yet.");
        update();
    }

    public void setSize(Dimension dmnsn) {
        layout.setSize(dmnsn);
        update();
    }

    public Dimension getSize() {
        return layout.getSize();
    }

    public void lock(T v, boolean bln) {
        layout.lock(v,bln);
    }

    public boolean isLocked(T v) {
        return layout.isLocked(v);
    }

    public void setLocation(T v, Point2D pd) {
        layout.setLocation(v, pd);
    }

    public Point2D transform(T i) {
        return layout.transform(i);
    }
    private void update(){

        int count = g.getVertices().size();
        
        Map<T,Integer> index;
        
        index = g.getIndexes();
        Map<Component,Integer> rows = new HashMap<Component,Integer>();

        for(T v: g.getVertices()){
            int column = index.get(v);
            
            Component component= ((Responsibility)v).getComponent();
            Integer row = rows.get(component);
            if(row == null){
                row = rows.size()+1;
                rows.put(component,row);
                System.out.println("COMPONENT:"+component);
            }
//            rows.put(column, row+1);
        }
         for(T v: g.getVertices()){    
            int column = index.get(v);
            Component component= ((Responsibility)v).getComponent();
            int row = rows.get(component);
            double step = rows.size()*1.2;
            int x = this.getSize().width*column/count;
            int y = (int) (this.getSize().height/step*row);
            
            layout.setLocation(v, new Point.Double(x,y));
            
            layout.lock(v, true);
         }
    }
//    private void update(){
//
//        int count = g.getVertices().size();
//        
//        Map<T,Integer> index;
//        
//        index = g.getIndexes();
//        Map<Integer,Integer> rows = new HashMap<Integer,Integer>();
//
//        for(T v: g.getVertices()){
//            int column = index.get(v);
//            
//            Integer row = rows.get(column);
//            if(row == null){
//                row = 1;
//            }
//            rows.put(column, row+1);
//            boolean sourceSink=false;
//            if(g.getPredecessorCount(v)>1 || g.getSuccessorCount(v)>1){
//                sourceSink=true;
//            }
//            double step = 2;
//            int x = this.getSize().width*column/count;
//            int y = (int) (this.getSize().height/step/4+(int)(this.getSize().height/step/4*((column%2)))+(int) (this.getSize().height/step/2*((row%2))));
//            if(sourceSink){
//                y+=this.getSize().height/(step*2);
//            }
//            layout.setLocation(v, new Point.Double(x,y));
//            
//            layout.lock(v, true);
//        }
//    }
}
